package com.epfresh.supplier.widget;

/**
 * Created by zhuli on 2017/8/22.
 */

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewParent;

import com.andview.refreshview.recyclerview.BaseRecyclerAdapter;
import com.daimajia.swipe.SwipeLayout;
import com.daimajia.swipe.implments.SwipeItemRecyclerMangerImpl;
import com.daimajia.swipe.interfaces.SwipeAdapterInterface;
import com.daimajia.swipe.interfaces.SwipeItemMangerInterface;
import com.daimajia.swipe.util.Attributes;

import java.util.ArrayList;
import java.util.List;

/**
 * RecyclerView基础适配器，结合左右划动与上下拉刷新。
 */
public abstract class RecyclerViewAdapter<T> extends BaseRecyclerAdapter implements ViewVariable, SwipeItemMangerInterface, SwipeAdapterInterface {
    private ArrayList<T> data;
    private OnItemClickListener mOnItemClickListener;

    /**
     * 构造方法
     *
     * @param data 数据
     */
    public RecyclerViewAdapter(ArrayList<T> data) {
        setData(data);
    }

    /**
     * 检查数据，如果为空则新建
     */
    protected void checkData() {
        if (null == data) {
            data = new ArrayList<>();
        }
    }

    /**
     * 返回当前适配器的数据列表项目总数
     *
     * @return 项目总数
     */
    @Override
    public int getAdapterItemCount() {
        checkData();
        return data.size();
    }

    /**
     * 返回当前适配器所有数据列表
     *
     * @return 数据
     */
    public ArrayList<T> getData() {
        checkData();
        return data;
    }

    /**
     * 设置当前适配器数据列表
     * 当传入的数据为空时 则新建一个数据列表
     * 当成功传入数据之后 刷新数据内容
     *
     * @param data 传入的数据
     */
    public void setData(ArrayList<T> data) {
        if (null == data) {
            data = new ArrayList<>();
        }
        this.data = data;
        closeAllItems();
        notifyDataSetChanged();
    }

    /**
     * 返回被判断项目，在当前适配器数据列表中的位置
     *
     * @param item 被判断的项目
     * @return 列表中的位置
     */
    public int indexOfItem(T item) {
        checkData();
        if (null == item) {
            for (int i = 0, j = data.size(); i < j; i++)
                if (null == data.get(i))
                    return i;
        } else {
            for (int i = 0, j = data.size(); i < j; i++)
                if (item.equals(data.get(i)))
                    return i;
        }
        return -1;
    }

    /**
     * 返回当前适配器数据列表中指定位置的项目
     *
     * @param position 指定的位置
     * @return 数据列表中的项目
     */
    public T getItem(int position) {
        checkData();
        if (-1 < position && position < data.size()) {
            return data.get(position);
        } else {
            return null;
        }
    }

    /**
     * 前适配器数据列表追加一个项目
     *
     * @param item 追加的项目
     */
    public void addItem(T item) {
        checkData();
        data.add(item);
        closeAllItems();
        notifyItemInserted(getItemCount());
    }

    /**
     * 前适配器数据列表追加一个之前没有的项目
     *
     * @param item 追加的项目
     */
    public void addNewItem(T item) {
        checkData();
        if (-1 < indexOfItem(item)) {
            data.add(item);
            closeAllItems();
            notifyItemInserted(getItemCount());
        }
    }

    /**
     * 删除前适配器数据列表中指定位置的项目
     *
     * @param position 指定的位置
     */
    public void removeItem(int position) {
        if (-1 < position && position < data.size()) {
            data.remove(position);
            closeAllItems();
            notifyItemRemoved(position);
            notifyItemRangeChanged(position, getItemCount());
        }
    }

    /**
     * 修改前适配器数据列表指定位置的项目
     *
     * @param position 指定的位置
     * @param item     修改后的项目
     */
    public void setItem(int position, T item) {
        checkData();
        if (-1 < position && position < data.size()) {
            data.set(position, item);
            closeAllItems();
            notifyItemChanged(position);
        }
    }

    /**
     * 项目点击事件监听器接口
     */
    public interface OnItemClickListener {

        /**
         * 当此适配器中的项目被点击时，回调此方法
         *
         * @param parent      此适配器在何处被点击
         * @param view        此适配器被点击的视图控监
         * @param position    视图控监在此适配器中的位置
         * @param swipeLayout 被点击项目所在滑动布局
         */
        void onItemClick(RecyclerView parent, View view, int position, SwipeLayout swipeLayout);
    }

    /**
     * 设置项目点击事件监听器
     *
     * @param onItemClickListener 点击事件监听器
     */
    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.mOnItemClickListener = onItemClickListener;
    }

    /**
     * 带点击事件的ViewHolder
     */
    protected class RecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        protected RecyclerViewHolder(View itemView, boolean isItem) {
            super(itemView);
            if (isItem) {
                // 设置黄油刀
//                ButterKnife.bind(this, itemView);
//                itemView.setOnClickListener(this);
            }
        }

        /**
         * 当视图控件被点击时回调方法 将OnClickListener转换为OnItemClickListener
         *
         * @param view 被点击的视图控件
         */
        @Override
        public void onClick(View view) {
            if (null != mOnItemClickListener) {
                RecyclerView recyclerView = getParent(view.getParent());
                if (null != recyclerView) {
                    SwipeLayout swipeLayout = null;
                    int position = getLayoutPosition();
                    int swipeLayoutResourceId = getSwipeLayoutResourceId(position);
                    if (swipeLayoutResourceId > 0) {
                        swipeLayout = (SwipeLayout) view.findViewById(swipeLayoutResourceId);
                    }
                    mOnItemClickListener.onItemClick(recyclerView, view, position, swipeLayout);
                }
            }
        }
    }

    protected RecyclerView getParent(ViewParent viewParent) {
        if (viewParent instanceof RecyclerView) {
            return (RecyclerView) viewParent;
        } else {
            if (null == viewParent.getParent()) {
                return null;
            } else {
                return getParent(viewParent.getParent());
            }
        }
    }

    private SwipeItemRecyclerMangerImpl mItemManger = new SwipeItemRecyclerMangerImpl(this);

    @Override
    public void openItem(int position) {
        mItemManger.openItem(position);
    }

    @Override
    public void closeItem(int position) {
        mItemManger.closeItem(position);
    }

    @Override
    public void closeAllExcept(SwipeLayout layout) {
        mItemManger.closeAllExcept(layout);
    }

    @Override
    public void closeAllItems() {
        mItemManger.closeAllItems();
    }

    @Override
    public List<Integer> getOpenItems() {
        return mItemManger.getOpenItems();
    }

    @Override
    public List<SwipeLayout> getOpenLayouts() {
        return mItemManger.getOpenLayouts();
    }

    @Override
    public void removeShownLayouts(SwipeLayout layout) {
        if (null != layout)
            mItemManger.removeShownLayouts(layout);
    }

    @Override
    public boolean isOpen(int position) {
        return mItemManger.isOpen(position);
    }

    @Override
    public Attributes.Mode getMode() {
        return mItemManger.getMode();
    }

    @Override
    public void setMode(Attributes.Mode mode) {
        mItemManger.setMode(mode);
    }

    public void bindView(View target, int position) {
        mItemManger.bindView(target, position);
    }
}
